import tkinter as tk
import tkinter.ttk as ttk
from tkinter import messagebox
from tkinter.simpledialog import Dialog

class CustomDialog(Dialog):
    def __init__(self, parent, title='自定义对话框'):
        self.name = ''
        self.age = ''
        self.geometry = '300x300'
        super().__init__(parent, title)

    def body(self, master):
        # 自定义样式
        style = ttk.Style()
        style.configure("TLabel", font=("SimHei", 10))
        style.configure("TEntry", padding=5)
        # 错误提示样式
        style.configure("Error.TLabel", font=("SimHei", 9), foreground="red")

        # 创建姓名输入区
        ttk.Label(master, text='姓名').grid(column=0, row=0, padx=5, pady=5, sticky='w')
        self.name_entry = ttk.Entry(master, width=30, style='TEntry')
        self.name_entry.grid(column=1, row=0, padx=5, pady=5, sticky='w')

        # 创建年龄输入区域
        ttk.Label(master, text='年龄').grid(column=0, row=1, padx=5, pady=5, sticky='w')
        self.age_entry = ttk.Entry(master, width=30, style='TEntry')
        self.age_entry.grid(column=1, row=1, padx=5, pady=5, sticky='w')

        # 错误提示标签（初始隐藏）
        self.error_label = ttk.Label(master, text='', style="Error.TLabel")
        self.error_label.grid(column=0, row=2, columnspan=2, padx=5, pady=2, sticky='w')

        return self.name_entry

    def buttonbox(self):
        # 创建按钮容器
        box = ttk.Frame(self)

        # 确认按钮
        ok_btn = ttk.Button(box, text='OK', command=self.validate_input)
        ok_btn.pack(side='left', padx=5, pady=5)

        # 取消按钮
        cancel_btn = ttk.Button(box, text='Cancel', command=self.cancel)
        cancel_btn.pack(side='left', padx=5, pady=5)

        # 绑定键盘事件
        self.bind('<Return>', lambda e: self.validate_input())
        self.bind('<Escape>', self.cancel)
        box.pack(pady=10)

    def validate_input(self):
        """验证输入合法性，合法则关闭对话框，否则显示错误提示"""
        self.name = self.name_entry.get().strip()
        self.age = self.age_entry.get().strip()

        # 清空之前的错误提示
        self.error_label.config(text='')

        # 验证逻辑
        if not self.name:
            self.error_label.config(text='❌ 姓名不能为空')
            self.name_entry.focus()  # 聚焦到错误输入框
            return  # 不关闭对话框

        if not self.age:
            self.error_label.config(text='❌ 年龄不能为空')
            self.age_entry.focus()
            return  # 不关闭对话框

        if not self.age.isdigit():
            self.error_label.config(text='❌ 年龄必须是数字')
            self.age_entry.focus()
            return  # 不关闭对话框

        # 所有验证通过，关闭对话框
        self.destroy()

    def cancel(self, event=None):
        # 取消时清空输入并关闭
        self.name = ''
        self.age = ''
        self.destroy()

    # 不需要重写apply方法，验证逻辑在validate_input中处理


if __name__ == '__main__':
    root = tk.Tk()
    root.geometry('400x300')
    root.title('输入错误不关闭对话框示例')
    result_label = ttk.Label(root, anchor='center', text='请点击按钮打开对话框', font=('SimHei', 15))
    result_label.pack(fill='x', pady=50)

    def open_dialog():
        dialog = CustomDialog(root, "输入相关信息")
        # 对话框关闭后，只有输入有效时才更新显示
        if dialog.name and dialog.age:
            result = f"姓名: {dialog.name}\n年龄: {dialog.age}"
            result_label.config(text=result)

    ttk.Button(root, text="点击打开输入框", command=open_dialog).pack(padx=5, pady=60)
    root.mainloop()
